﻿using Abp.Application.Features;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Events.Bus;
using Abp.Events.Bus.Factories;
using Abp.Events.Bus.Handlers;
using Abp.Runtime.Validation;
 
using hhg.PersonDomain;
using hhg.TaskDomain;
using hhg.Users;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
namespace hhg
{
    public class TaskAppService: ApplicationService,ITaskAppService
    {
        private readonly ITaskRepository  _taskRepository;
        private readonly IRepository<Person> _personRepository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;

        public IEventBus EventBus { get; set; }

        public TaskAppService(ITaskRepository taskRepository ,IRepository<Person> personRepository)
        {
            _taskRepository = taskRepository;
            _personRepository = personRepository;
             
            EventBus = NullEventBus.Instance;

            base.Logger.Info("new TaskAppService at :"+DateTime.Now);
        }
        public async System.Threading.Tasks.Task<PersonDto> GetReportToExcel()
        {
            if (await FeatureChecker.IsEnabledAsync("ExportToExcel"))
            {
                throw new AbpAuthorizationException("You don't have this feature: ExportToExcel");
            }
            return new PersonDto();
        }
        public void UpdateTask(UpdateTaskInput input)
        {
            
            //可以直接Logger,它在ApplicationService基类中定义的
            Logger.Info("Updating a task for input: " + input);

            //通过仓储基类的通用方法Get，获取指定Id的Task实体对象
            var task = _taskRepository.Get(input.TaskId);

            //修改task实体的属性值
            if (input.State.HasValue)
            {
                task.State = input.State.Value;
            }

            if (input.AssignedPersonId.HasValue)
            {
                task.AssignedPerson = _personRepository.Load(input.AssignedPersonId.Value);
            }
           
            //我们都不需要调用Update方法
            //因为应用服务层的方法默认开启了工作单元模式（Unit of Work）
            //ABP框架会工作单元完成时自动保存对实体的所有更改，除非有异常抛出。有异常时会自动回滚，因为工作单元默认开启数据库事务。
        }
       
        public void CreateTask(CreateTaskInput input)
        {
            Logger.Info("Creating a task for input: " + input);

           

            //通过输入参数，创建一个新的Task实体
            var task = new Task { Description = input.Description };

            if (input.AssignedPersonId.HasValue)
            {
                task.AssignedPersonId = input.AssignedPersonId.Value;
            }

            //调用仓储基类的Insert方法把实体保存到数据库中
            _taskRepository.Insert(task);
            EventBus.Trigger(new TaskCompletedEventData { TaskId = 42 });

            EventBus.Register<TaskCompletedEventData>(eventData =>
            {
                //WriteActivity("A task is completed by id = " + eventData.TaskId);
            });
            //base.CurrentUnitOfWork.SaveChanges();
        }

        public IEnumerable<Task> GetPageList()
        {
            return _taskRepository.GetAll();
        }

        public void CompleteTask(string input)
        {
            //TODO: 已完成数据库上的任务
            EventBus.Trigger(new TaskCompletedEventData { TaskId = 42 });
            EventBus.Register<TaskCompletedEventData>(eventData =>
            {
               // WriteActivity("A task is completed by id = " + eventData.TaskId);
            });

        }
    }
    public class TaskCompletedEventData : EventData
    {
        public int TaskId { get; set; }
    }
   

    public class TaskEventData : EventData
    {
        public Task Task { get; set; }
    }

    public class TaskCreatedEventData : TaskEventData
    {
        public User CreatorUser { get; set; }
    }
     

    public class ActivityWriter :
      IEventHandler<TaskCompletedEventData>,
      IEventHandler<TaskCreatedEventData>,
      ITransientDependency
    {
        public void HandleEvent(TaskCompletedEventData eventData)
        {
            //TODO: 处理事件
        }
        public void HandleEvent(TaskCreatedEventData eventData)
        {
            //TODO: 处理事件
        }
    }

    /// <summary>
    /// 最后,你可以注册一个事件处理器工厂(event handler factory)来负责创建处理器。处理器工厂有两个方法: GetHandler和ReleaseHandler,范例如下:
    /// </summary>
    public class ActivityWriterFactory : IEventHandlerFactory
    {
        public IEventHandler GetHandler()
        {
            return new ActivityWriter();
        }
        public void ReleaseHandler(IEventHandler handler)
        {
            //TODO: 释放ActivityWriter实体(处理器)
        }
    }
    public class GetTasksInput : IInputDto, IShouldNormalize
    {
        public string Sorting { get; set; }

        public void Normalize()
        {
            if (string.IsNullOrWhiteSpace(Sorting))
            {
                Sorting = "Name ASC";
            }
        }
    }

    public class SearchPeopleInput : IInputDto
    {
        [StringLength(40, MinimumLength = 1)]
        public string SearchedName { get; set; }
    }

    public class SearchPeopleOutput : IOutputDto
    {
        public List<PersonDto> People { get; set; }
    }

    public class PersonDto : EntityDto
    {
        public string Name { get; set; }
        public string EmailAddress { get; set; }
    }
}
